<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>内存对齐『核对版』 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/24.6f596516.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/15.fbdfc4ee.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/2.570d8a23.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/25.14067b60.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/30.805597a8.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/5.6f47322c.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link router-link-active">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link router-link-active">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>内存对齐『核对版』</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_00-参考资料『记忆』⭐️" class="sidebar-link">00.参考资料『记忆』⭐️</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#✔️⭐️参考资料" class="sidebar-link">✔️⭐️参考资料</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_01-内存对齐前述❎" class="sidebar-link">01.内存对齐前述❎</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_1-1-是否可以强制不内存对齐？" class="sidebar-link">1.1.是否可以强制不内存对齐？</a></li></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_02-前置知识—可移植性『基本类型的对齐数』" class="sidebar-link">02.前置知识—可移植性『基本类型的对齐数』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_2-1-记忆『核心』⭐️" class="sidebar-link">2.1.记忆『核心』⭐️</a></li></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#测试环境" class="sidebar-link">测试环境</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_02-实验观察内存对齐❎" class="sidebar-link">02.实验观察内存对齐❎</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_03-结构体内存对齐规则『核心』" class="sidebar-link">03.结构体内存对齐规则『核心』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-3-自然对齐和规则1：基本类型对齐" class="sidebar-link">3.3.自然对齐和规则1：基本类型对齐</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-2-规则对齐和规则2：struct和union的数据成员对齐规则" class="sidebar-link">3.2.规则对齐和规则2：struct和union的数据成员对齐规则</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-3-综合方法" class="sidebar-link">3.3.综合方法</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-4-坑点：" class="sidebar-link">3.4.坑点：</a></li></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_05-杠筋？" class="sidebar-link">05.杠筋？</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_5-1-测试环境（推翻第2条规则）♻️" class="sidebar-link">5.1.测试环境（推翻第2条规则）♻️??</a></li></ul></li><li><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_03-典例解释" class="sidebar-link">03.典例解释</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-1-单个struct『good解释⭐️" class="sidebar-link">3.1.单个struct『Good解释⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-2-单个union『复杂内存对齐分析（面试）』" class="sidebar-link">3.2.单个union『复杂内存对齐分析（面试）』</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-3-单个位段" class="sidebar-link">3.3.单个位段</a></li><li class="sidebar-sub-header"><a href="/01.Language/C/%E6%A0%B8%E5%BF%83%E7%9F%A5%E8%AF%86/04.%E5%86%85%E5%AD%98%E5%AF%B9%E9%BD%90.html#_3-4-数组和指针组合『难题』" class="sidebar-link">3.4.数组和指针组合『难题』</a></li></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="内存对齐『核对版』"><a href="#内存对齐『核对版』" class="header-anchor">#</a> 内存对齐『核对版』</h1> <h2 id="_00-参考资料『记忆』⭐️"><a href="#_00-参考资料『记忆』⭐️" class="header-anchor">#</a> 00.参考资料『记忆』⭐️</h2> <ul><li>01.转载<a href="https://mp.weixin.qq.com/s?__biz=MjM5NTY1MjY0MQ==&mid=2650753100&idx=4&sn=10fb278995426d9c5bcc07309d39c6f1&chksm=befedd0289895414c5e3b3ed0a952d3a0438e15e85e992129773b349b8e8f9b8590c6fc9167a&mpshare=1&scene=23&srcid=1005yjd59tg3vG08SxTS9Rnm&sharer_sharetime=1601910589841&sharer_shareid=7d02bdfe8ee477ab2b773f2df63f3163#rd" target="_blank" rel="noopener noreferrer">传送门（PS：此文章中有错误的地方，下面自行改正了）<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>02.CSDN官方转载，<a href="https://mp.weixin.qq.com/s?__biz=MjM5MjAwODM4MA==&mid=2650793413&idx=3&sn=c0f6071b066b36440987dcbca4a64a91&chksm=bea7941689d01d00c5a53fb09fdb22ff14d056534bbec112d10847f3c3562bb81a3bdcb5ebd9&mpshare=1&scene=23&srcid=03070oITnw7pdgZ3yeCUirqz&sharer_sharetime=1615116737628&sharer_shareid=7d02bdfe8ee477ab2b773f2df63f3163#rd" target="_blank" rel="noopener noreferrer">技术让梦想更伟大<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>『很不错』</li> <li><font style="background:yellow;">记忆下面的核心：已知<code>#pragma pack(n)就能全部解决</code></font> <ul><li>1』32位编译器<code>#pragma pack(4)</code>，64位编译<code>#pragma pack(8)</code></li> <li>2、3.结构体总大小为最大对齐数的整数倍<font style="background:yellow;">（max（各个成员变量的<strong>由（规则2）获得的对齐数大小</strong>））</font>
（每个成员变量都有自己的对齐数）『是的，这个才是核心！后边我对有个测试的判断，写错了』</li> <li>比如理解就是
<ul><li><code>int</code>类型在<code>16</code>位机器上，是2个字节和2个字节『而不是4个字节』</li> <li><code>double</code>在<code>32</code>位机器上，是4个字节和4个字节『而不是8个字节』</li></ul></li> <li>注意：<font style="background:yellow;">讲字节对齐的时候，不告知CPU位数和操作系统和编译器位数就是耍流氓！</font></li></ul></li></ul> <h2 id="✔️⭐️参考资料"><a href="#✔️⭐️参考资料" class="header-anchor">#</a> ✔️⭐️参考资料</h2> <ul><li>《C++反汇编与逆向分析技术揭秘》，P209-P212</li></ul> <blockquote><p>内存对齐步骤</p></blockquote> <ul><li>1、在为结构体和类中的数据成员分配内存时，结构体中的<strong>当前数据成员类型长度M</strong>，<strong>指定的对齐值为N</strong>，那么实际对齐值为**==q=min(M , N)==**，其成员的地址安排在q的倍数上「P209」</li> <li>2、讨论一下对齐值对结构体整体大小的影响。并非设定了默认对齐值就将结构体的对齐值锁定。如果**==结构体中数据成员类型最大值为M==<strong>，<strong>指定的对齐值为N</strong>，那么实际对齐值为</strong>==min(M , N)==**「P210」</li></ul> <h2 id="_01-内存对齐前述❎"><a href="#_01-内存对齐前述❎" class="header-anchor">#</a> 01.内存对齐前述❎</h2> <p>原因:<font color="red">现代的计算机中，有一个内存对齐的要求</font></p> <p><b>PS：现代计算机中内存空间都是按照字节划分的，所以图示中一个黑色的长条代表一个字节。 </b></p> <p>例:有些平台<b>每次读都是从偶地址</b>开始的  『笔者认为，也可以是从2的倍数，从4的倍数，8的倍数开始。。
如果一个int型（假设为32位系统）</p> <ul><li>1）如果他存放在<b>偶地址</b>开始的地方，那么一个CPU读的周期，就可以读出这个32bit的int</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/2020_06_08_1.png" alt="2020_06_08_1"></p> <ul><li>2）如果他存放在<b>奇地址</b>开始的地方，那么我们要是想要读取，蓝色的部分的int，我们的CPU需要读两个红色的框框。在第一个4字节块,剔除不想要的字节（0地址）,然后从地址4开始读取下一个4字节块,同样剔除不要的数据（5，6，7地址）,最后将留下的两块数据合并放入寄存器。也就是说这种情况CPU需要2个读周期，并且对两次读出的结果的高低字节进行拼凑才能得到这个32位bit的数据。<br>
很显然，这个在读取的效率上下降了很多。</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/2020_06_08_2.png" alt="2020_06_08_2"></p> <p>此处肯定有疑惑</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>- Q:难道就不能直接从那个奇地址开始读吗？    
- A:理论上讲，我们对任何类型的变量的访问可以从任何奇或者偶地址开始，这样是可以的。
但是，我们的硬件在设计的时候，CPU的底层访问实现的似乎就是这个，每次从偶地址开始读取。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>总的来说，内存对齐一般是由于以下原因：</p> <ul><li>1）<b>平台原因（移植原因）</b>：不是所有的硬件平台都能访问任意地址上的任意数据的；某些硬件平台只能在某些地址处取某些特定类型的数据，否则抛出硬件异常。（有的硬件的设计就是只支持从偶地址开始访问的）</li> <li>2）<b>性能原因（根本原因）</b>：数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于，为了访问未对齐的内存，处理器需要作两次内存访问（前面我们的例子就是这样）；而对齐的内存访问仅需要一次访问。</li> <li>我们要提高CPU访问内存数据的<b>效率</b>的问题。</li> <li>计算机访问内存一般是以内存块为单位的，块的大小是地址对齐的。如4,8,16字节对齐等。</li> <li>一般来说对齐是跟CPU位数及CPU特性有关的，具体的比如X86-64支持1,2,4,8字节对齐.所以里面的讲的对齐主要还是取决于C语言中数据类型的大小。
PS：<b>对齐值必须是2的幂次方</b>，如1，2，4，8，16。如果一个变量按n字节对齐，那么该变量的起始地址必须是n的倍数。
每个<b>特定平台</b>上的编译器都有自己默认的“对齐系数”，可以通过设置<code>#pragma pack(n)</code>告诉编译器，是n字节对齐。</li></ul> <h3 id="_1-1-是否可以强制不内存对齐？"><a href="#_1-1-是否可以强制不内存对齐？" class="header-anchor">#</a> 1.1.是否可以强制不内存对齐？</h3> <ul><li>笔者觉得可以，但是那样会导致CPU效率降低</li></ul> <h2 id="_02-前置知识—可移植性『基本类型的对齐数』"><a href="#_02-前置知识—可移植性『基本类型的对齐数』" class="header-anchor">#</a> 02.前置知识—可移植性『基本类型的对齐数』</h2> <ul><li><p>《Java核心技术卷1》说道：<strong>与C和C++不同，Java规范中没有“依赖具体实现”的地方</strong>！基本数据类型大小以及有关运算都做了明确的说明！</p> <ul><li><strong>Java中int永远是32位的整数</strong></li> <li><font style="background:yellow;">而<code>在C和C++中，int可能是16位整数、32位整数、也可能是『编译器提供商』指定的其他大小</code>。唯一的限制只是：int类型的大小不低于<code>short int</code>，并且不能高于<code>long int</code></font></li> <li>在Java中，数据类型具有固定的大小、这消除了代码移植时令人头痛的问题。</li></ul></li></ul> <h3 id="_2-1-记忆『核心』⭐️"><a href="#_2-1-记忆『核心』⭐️" class="header-anchor">#</a> 2.1.记忆『核心』⭐️</h3> <p><code>int，long int，short int</code> 的宽度和<strong>机器字长</strong>及<strong>编译器</strong>有关,但一般都有以下规则（ANSI/ISO制订的）</p> <ul><li><p><code>sizeof(short int) &lt;= sizeof(int)</code></p></li> <li><p><code>sizeof(int) &lt;= sizeof(long int)</code></p></li> <li><p><code>short int</code> 至少应为16位（2字节）</p></li> <li><p><code>long int</code> 至少应为32位</p></li></ul> <table><thead><tr><th style="text-align:left">数据类型</th> <th style="text-align:left">16位编译器</th> <th style="text-align:left">32位编译器</th> <th style="text-align:left">64位编译器</th></tr></thead> <tbody><tr><td style="text-align:left">char</td> <td style="text-align:left">1字节</td> <td style="text-align:left">1字节</td> <td style="text-align:left">1字节</td></tr> <tr><td style="text-align:left">『指针』char*</td> <td style="text-align:left">2字节</td> <td style="text-align:left">4字节</td> <td style="text-align:left">8字节</td></tr> <tr><td style="text-align:left">short int</td> <td style="text-align:left">2字节</td> <td style="text-align:left">2字节</td> <td style="text-align:left">2字节</td></tr> <tr><td style="text-align:left">int</td> <td style="text-align:left"><strong>2字节</strong></td> <td style="text-align:left"><strong>4字节</strong></td> <td style="text-align:left"><strong>4字节</strong></td></tr> <tr><td style="text-align:left">unsigned int</td> <td style="text-align:left">2字节</td> <td style="text-align:left">4字节</td> <td style="text-align:left">4字节</td></tr> <tr><td style="text-align:left">float</td> <td style="text-align:left">4字节</td> <td style="text-align:left">4字节</td> <td style="text-align:left">4字节</td></tr> <tr><td style="text-align:left">double</td> <td style="text-align:left">8字节</td> <td style="text-align:left">8字节</td> <td style="text-align:left">8字节</td></tr> <tr><td style="text-align:left">long</td> <td style="text-align:left"><strong>4字节</strong></td> <td style="text-align:left"><strong>4字节</strong></td> <td style="text-align:left"><strong>8字节</strong></td></tr> <tr><td style="text-align:left">long long</td> <td style="text-align:left"><strong>8字节</strong></td> <td style="text-align:left"><strong>8字节</strong></td> <td style="text-align:left"><strong>8字节</strong></td></tr> <tr><td style="text-align:left">unsigned long</td> <td style="text-align:left">4字节</td> <td style="text-align:left">4字节</td> <td style="text-align:left">8字节</td></tr></tbody></table> <h2 id="测试环境"><a href="#测试环境" class="header-anchor">#</a> 测试环境</h2> <div class="language-bash line-numbers-mode"><pre class="language-bash"><code><span class="token punctuation">[</span>root@CentosLinux ~<span class="token punctuation">]</span><span class="token comment"># uname -m</span>
x86_64
<span class="token punctuation">[</span>root@CentosLinux ~<span class="token punctuation">]</span><span class="token comment"># uname -a</span>
Linux CentosLinux <span class="token number">3.10</span>.0-1127.19.1.el7.x86_64 <span class="token comment">#1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><ul><li>cpu信息<code>lscpu</code></li></ul> <div class="language-bash line-numbers-mode"><pre class="language-bash"><code>Architecture:          x86_64
CPU op-mode<span class="token punctuation">(</span>s<span class="token punctuation">)</span>:        <span class="token number">32</span>-bit, <span class="token number">64</span>-bit
Byte Order:            Little Endian
CPU<span class="token punctuation">(</span>s<span class="token punctuation">)</span>:                <span class="token number">1</span>
On-line CPU<span class="token punctuation">(</span>s<span class="token punctuation">)</span> list:   <span class="token number">0</span>
Thread<span class="token punctuation">(</span>s<span class="token punctuation">)</span> per core:    <span class="token number">1</span>
Core<span class="token punctuation">(</span>s<span class="token punctuation">)</span> per socket:    <span class="token number">1</span>
Socket<span class="token punctuation">(</span>s<span class="token punctuation">)</span>:             <span class="token number">1</span>
NUMA node<span class="token punctuation">(</span>s<span class="token punctuation">)</span>:          <span class="token number">1</span>
Vendor ID:             GenuineIntel
CPU family:            <span class="token number">6</span>
Model:                 <span class="token number">94</span>
Model name:            Intel<span class="token punctuation">(</span>R<span class="token punctuation">)</span> Xeon<span class="token punctuation">(</span>R<span class="token punctuation">)</span> Gold <span class="token number">6148</span> CPU @ <span class="token number">2</span>.40GHz
Stepping:              <span class="token number">3</span>
CPU MHz:               <span class="token number">2394.374</span>
BogoMIPS:              <span class="token number">4788.74</span>
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              4096K
L3 cache:              28160K
NUMA node0 CPU<span class="token punctuation">(</span>s<span class="token punctuation">)</span>:     <span class="token number">0</span>
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><h2 id="_02-实验观察内存对齐❎"><a href="#_02-实验观察内存对齐❎" class="header-anchor">#</a> 02.实验观察内存对齐❎</h2> <p>例题5：（分析下面在32位编译环境的程序）</p> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression"><span class="token function">pack</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span></span></span>

<span class="token comment">//要是不加#pragma pack(2)，则是默认4字节对齐，我们其实可以看做#pragma pack(4)</span>
<span class="token keyword">struct</span><span class="token punctuation">{</span>
    <span class="token keyword">char</span> c1<span class="token punctuation">;</span>
    <span class="token keyword">char</span> c2<span class="token punctuation">;</span>
    <span class="token keyword">int</span> i<span class="token punctuation">;</span>
<span class="token punctuation">}</span>demo<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>demo<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//输出为6   //因为加了#pragma pack(2)，根据规则2可以知道也是6</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h2 id="_03-结构体内存对齐规则『核心』"><a href="#_03-结构体内存对齐规则『核心』" class="header-anchor">#</a> 03.结构体内存对齐规则『核心』</h2> <ul><li><p>Tips：C语言和C++允许你用预编译来干预内存对齐</p> <ul><li>比如用<code>#pragma pack</code>来干预。</li></ul></li> <li><p><font style="background:yellow;">不同平台上<strong>编译器</strong>的 <code>pragma pack</code> 默认值不同。而我们可以通过预编译命令<code>#pragma pack(n)</code>, n= 1,2,4,8,16来改变对齐系数。</font></p> <ul><li>现代计算机读取数据的时候，都是一次性读取一个内存块，比如4字节。（更准确来说是与数据线根数有关，所以说，其实现在都是64位的CPU，一次性能够读取8字节）</li></ul></li> <li><p><font style="background:yellow;">一般<strong>内存块</strong>对齐方式『核心之一』：</font></p> <ul><li>16位CPU机器默认2字节对齐『<code>#pragma pack(2)</code>』</li> <li>32位CPU机器默认4字节对齐『<code>#pragma pack(4)</code>』</li> <li>64位CPU机器上的64位编译器默认8字节对齐『<code>#pragma pack(8)</code>』</li></ul></li></ul> <blockquote><p><strong>内存对齐又分为『自然对齐』和『规则对齐』</strong></p></blockquote> <h3 id="_3-3-自然对齐和规则1：基本类型对齐"><a href="#_3-3-自然对齐和规则1：基本类型对齐" class="header-anchor">#</a> 3.3.自然对齐和规则1：基本类型对齐</h3> <ul><li><p>指的是将对应变量类型存入对应地址值的内存空间，即数据要根据其数据类型存放到以其数据类型为倍数的地址处。</p> <ul><li>例如 char 类型占1个字节空间，1的倍数是所有数，因此可以放置在任何允许地址处</li> <li>而int类型占4个字节空间，以4为倍数的地址就有0,4,8等。</li></ul></li> <li><p>编译器会优先按照自然对齐进行数据地址分配。</p></li> <li><p><strong>基本类型</strong>的对齐值就是其<code>sizeof</code>获得值；</p> <ul><li><font style="background:yellow;">『坑点：比如<code>int在16位的编译器上是sizeof(int)=2</code>』</font></li></ul></li> <li><p>我们在进行基本类型对齐的同时，我们<strong>要尽量保证每个变量整体能放到1个或者2个内存块当中</strong>，并且要尽可能的小。也就是能放在1个内存块，绝不放2个，否则会降低效率，比如先前图片中int放的位置。</p></li> <li><p>对于标准数据类型，它的地址只要是它的长度的整数倍就行了。</p></li> <li><p>非标准数据类型按下面的原则对齐：</p></li> <li><p>数组：按照基本数据类型对齐，第一个对齐了后面的自然也就对齐了。</p></li> <li><p>联合：按其包含的长度最大的数据类型对齐。</p></li> <li><p>结构体：结构体中每个数据类型都要对齐。</p></li></ul> <h3 id="_3-2-规则对齐和规则2：struct和union的数据成员对齐规则"><a href="#_3-2-规则对齐和规则2：struct和union的数据成员对齐规则" class="header-anchor">#</a> 3.2.规则对齐和规则2：<code>struct</code>和<code>union</code>的数据成员对齐规则</h3> <ul><li><p><b>结构(struct)和联合(union))的数据成员</b>对齐规则：</p> <ul><li>在数据成员完成各自对齐之后，结构和联合<strong>本身</strong>也要进行对齐。</li> <li>1—<b>未改变默认规定对齐值</b>，对齐将按照结构或联合整体<code>sizeof</code>和<code>默认的机器字节对齐</code>中，比较小的那个进行;</li> <li>2—<b>修改了默认规定对齐值</b>，比如<code>#pragma pack(n)</code>，对齐将按照<code>#pragma pack(n)</code>指定的数值和结构(或联合)<code>sizeof</code>获得值中<b>小</b>的那个进行;</li></ul></li> <li><p>以『<strong>结构体</strong>』为例就是在自然对齐后，编译器将对『自然对齐』产生的『空隙内存』填充无效数据，且填充后结构体占<strong>内存空间</strong>为结构<strong>体内</strong>占内存空间<font style="background:yellow;">最大的数据类型成员变量</font>的整数倍。</p></li></ul> <h5 id="_1、难点1—double『测试坑』⭐️『其实说的就是“可移植性”』"><a href="#_1、难点1—double『测试坑』⭐️『其实说的就是“可移植性”』" class="header-anchor">#</a> 1、难点1—double『测试坑』⭐️『其实说的就是“可移植性”』</h5> <ul><li>我们知道32位处理器一次只能处理32位也就是4个字节的数据，而 double 是8字节数据类型，这要怎么处理呢？</li> <li>『如果是<strong>64位处理器</strong>，8字节数据可以一次处理完毕』，而在32位处理器下，为了也能处理 double8 字节数据，在处理的时候将<strong>会把 double <font style="background:yellow;">拆分</font>成两个4字节数进行处理</strong>，从这里就会出现一种情况如下：</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">test_32</span>
<span class="token punctuation">{</span>
     <span class="token keyword">char</span> a<span class="token punctuation">;</span>
     <span class="token keyword">char</span> b<span class="token punctuation">;</span>
     <span class="token keyword">double</span> c<span class="token punctuation">;</span>
<span class="token punctuation">}</span>test_32<span class="token punctuation">;</span> 
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><ul><li>这个结构体在32位下所占内存空间为12字节，只能拆分成两个4字节进行处理，所以这里规则对齐将判定该结构体最大数据类型长度为4字节，因此总长度为4字节的整数倍，也就是12字节。</li> <li>这个结构体在64位环境下所占内存空间为16字节，而64位判定最大为8字节，所以结果也是8字节的整数倍：16字节。这里的结构体中的double没有按照自然对齐放置到理论上的8字节倍数地址处，我认为这里编译器也有根据规则对齐做出相应的优化，节省了4个多余字节</li></ul> <p>测试代码如下：环境『Linux64位』</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">test_32</span>
<span class="token punctuation">{</span>
 <span class="token keyword">char</span> a<span class="token punctuation">;</span>
 <span class="token keyword">char</span> b<span class="token punctuation">;</span>
 <span class="token keyword">double</span> c<span class="token punctuation">;</span>
<span class="token punctuation">}</span>test_32<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>

        cout<span class="token operator">&lt;&lt;</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span> test_32<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
    	cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>a<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>b<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//输入是16</span>
<span class="token comment">//0</span>
<span class="token comment">//1</span>
<span class="token comment">//8</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><p>更改字节对齐之后『反向知晓，<font style="background:yellow;">64位Linux的g++默认对齐数是8字节</font>』</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression"><span class="token function">pack</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span></span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">typedef</span> <span class="token keyword">struct</span> <span class="token class-name">test_32</span>
<span class="token punctuation">{</span>
 <span class="token keyword">char</span> a<span class="token punctuation">;</span>
 <span class="token keyword">char</span> b<span class="token punctuation">;</span>
 <span class="token keyword">double</span> c<span class="token punctuation">;</span>
<span class="token punctuation">}</span>test_32<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>

        cout<span class="token operator">&lt;&lt;</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span> test_32<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
    	cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>a<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>b<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
        cout<span class="token operator">&lt;&lt;</span><span class="token function">offsetof</span><span class="token punctuation">(</span>test_32<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>

        <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//输入是12</span>
<span class="token comment">//</span>
<span class="token comment">//0</span>
<span class="token comment">//1</span>
<span class="token comment">//4</span>

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><blockquote><p>我的猜想：</p> <p>1、默认字节对齐的本质：CPU一次性寻址的字节长度</p> <p>2、自然对齐中min(默认的对齐数，这个基本类型的字节数)『设置4字节对齐之后，看到了，本猜想正确』</p> <p>3、本次测试，好像推翻了『规则对齐。。。。</p> <p>规则对齐改为？？规则对齐，取我们实际上》》》》。。。不清楚</p> <p>我觉得可这么想，由于min(4，double)获得的是4，所以在自然对齐的时候，我们被迫将double分成两半</p> <p>然后，规则对齐的时候，虽然结构体中最大显然是8，应该是8的倍数，但是被『编译器优化了』觉得后面的『补充不需要了，所以，才采取的12，而不是16，</p> <p>进一步猜测：<font style="background:yellow;">补全空格，只补充中间的，不补充最末尾的？『这个猜想，和下面的黄色部分，我觉得是对的，模型建立完毕』</font></p></blockquote> <p>修正知道：对齐长度『长于』struct中的类型长度『最长』的值时,设置的对齐长度等于无用</p> <ul><li><p><font style="background:yellow;">故当我们将 #pragma pack 的n值小于『所有数据成员长度』的时候，结果将改变。</font></p></li> <li><p>或许上面就是，我们使用pack(4)之后是12的原因？？</p></li></ul> <h5 id="_2、数组『1个易错』"><a href="#_2、数组『1个易错』" class="header-anchor">#</a> 2、<strong>数组</strong>『1个易错』</h5> <ul><li>对齐值为：<strong>min(数组元素类型，编译器默认对齐长度/修改后)</strong>。</li> <li>易错：数组对齐的长度是按照『数组成员类型』长度来比对的</li> <li>但数组中的元素是连续存放，存放时还是按照数组实际的长度。如char t[9]，对齐长度为1，实际占用连续的9byte。然后根据下一个元素的对齐长度决定在下一个元素之前填补多少byte</li></ul> <h5 id="_3、嵌套的结构体"><a href="#_3、嵌套的结构体" class="header-anchor">#</a> 3、<strong>嵌套的结构体</strong></h5> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">struct</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
  <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
  <span class="token keyword">struct</span> <span class="token class-name">B</span> b<span class="token punctuation">;</span>
  <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">//对于B结构体在A中的对齐长度为：</span>
<span class="token comment">//min(	B结构体的对齐长度	,	编译器默认对齐长度/修改后	)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h3 id="_3-3-综合方法"><a href="#_3-3-综合方法" class="header-anchor">#</a> 3.3.综合方法</h3> <ul><li><code>#pragma pack</code>可以修改，『编译器默认对齐数』，修改之后，下面的那个对齐规则一律换成改后的！</li></ul> <h4 id="_1、首先『自然对齐』"><a href="#_1、首先『自然对齐』" class="header-anchor">#</a> 1、首先『自然对齐』</h4> <ul><li>1.第1个<strong>数据成员</strong>在『<strong>结构</strong>(struct)/<strong>联合</strong>(union)』变量offset偏移量为0 的地址处，也就是第一个成员必须从头开始。『原因：很显然，1,2,4,8的共同的倍数都是0，因为0乘以任何数都是0』</li> <li>2.其他<b>成员变量</b>要对齐到某个数字（对齐数）的整数倍的地址处。对齐数为『编译器默认的对齐数』与该成员大小中的较小值<font style="background:yellow;">（min（编译器默认对齐数，成员变量大小））</font>。『自然对齐，审核正确』</li> <li><font style="background:yellow;">Linux中gcc和g++编译器，32位默认对齐数是4字节对齐。64位默认字节对齐数是8字节对齐。</font>（后续有证明，注意，参考的“脚本之家”那个有误）此外默认对齐数可以通过#pragma pack（）修改，但修改只能设置成1，2，4，8，16。</li></ul> <h4 id="_2、然后『规则对齐』"><a href="#_2、然后『规则对齐』" class="header-anchor">#</a> 2、然后『规则对齐』</h4> <ul><li>3.<b>结构体总大小</b>为最大对齐数的整数倍<font style="background:yellow;">（max（各个成员变量的由（规则2）获得的对齐数大小））</font>。（每个成员变量都有自己的对齐数）『规则对齐，应该错误，应该不是由规则2获得的，而是直接所以成员变量』</li> <li>4.如果嵌套结构体，被嵌套的结构体对齐到『自己的最大对齐数』的整数倍处，（<strong>其实就是，我们将这个结构体也看作1个普通的类型 变量</strong>，这个思想有的像『递归』的定义『『『如果一个结构里有某些结构体成员，则结构体成员要从其内部&quot;最宽<strong>基本类型</strong>成员&quot;的整数倍地址开始存储』』』）结构体的整体大小就是所有最大对齐数（包含嵌套结构体的对齐数）的整数倍。</li></ul> <blockquote><p>其他：可借助，<font style="background:yellow;">C语言头文件中<code>#include&lt;stddef.h&gt;</code>中函数<code>offsetof</code>观察现象</font></p></blockquote> <h3 id="_3-4-坑点："><a href="#_3-4-坑点：" class="header-anchor">#</a> 3.4.坑点：</h3> <ul><li>结构体中union等，要是没有实例化，并且没有其他元素，那么不用算他占的大小
<ul><li>如果，仅仅只有它，需要算1个字节，毕竟如果不算，那就不好表述struct了 『类似问，空class是多大』</li></ul></li></ul> <h2 id="_05-杠筋？"><a href="#_05-杠筋？" class="header-anchor">#</a> 05.杠筋？</h2> <h3 id="_5-1-测试环境（推翻第2条规则）♻️"><a href="#_5-1-测试环境（推翻第2条规则）♻️" class="header-anchor">#</a> 5.1.测试环境（推翻第2条规则）♻️??</h3> <ul><li>64位的CPU</li> <li>64位的OS，装的64位的DevC++「无伤大雅」</li> <li>但是编译器选择<code>DevC++ 32bit Release版本</code></li> <li>运行环境，还是在这个64位的机器上</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">xx</span>
<span class="token punctuation">{</span>
    <span class="token keyword">long</span> <span class="token keyword">long</span> _x1<span class="token punctuation">;</span>
    <span class="token keyword">char</span> _x2<span class="token punctuation">;</span>
    <span class="token keyword">int</span> _x3<span class="token punctuation">;</span>
    <span class="token keyword">char</span> _x4<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">static</span> <span class="token keyword">int</span> _x5<span class="token punctuation">;</span>  
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> xx<span class="token operator">::</span>_x5<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>xx<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token function">offsetof</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span>_x1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token function">offsetof</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span>_x2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token function">offsetof</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span>_x3<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token function">offsetof</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span>_x4<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token function">offsetof</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span>_x4<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br></div></div><p>测试</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>24
0
8
12
16
17
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h4 id="_5-1-1-『看似解释不通？』，如果按照先前的解释方式"><a href="#_5-1-1-『看似解释不通？』，如果按照先前的解释方式" class="header-anchor">#</a> 5.1.1.『看似解释不通？』，如果按照先前的解释方式:</h4> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>_x1 对齐数 min(long long,4)=4   0-7
_x2 对齐数 min(char,4)=1		8
_x3 对齐数 min(int,4)=4			12-15
_x4 对齐数 min(char,4)=1		16-17	（易错点，注意是char，而不是2个char）
整体字节对齐
max(4,1,4,1)=4
那么20字节就OK了，但是这样不对？？？？为什么？？『我的解释在后边！！』
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h4 id="_5-1-2-最新解释"><a href="#_5-1-2-最新解释" class="header-anchor">#</a> 5.1.2.最新解释</h4> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>_x1 对齐数 min(long long,4)=4   0-7
_x2 对齐数 min(char,4)=1		8
_x3 对齐数 min(int,4)=4			12-15
_x4 对齐数 min(char,4)=1			16-17

整体字节对齐
max(long long,char ,int , char)=8
那么24字节才OK
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><ul><li>结构体的最终大小必须是结构体最大简单类型的整数倍？？？</li> <li>A：2021年7.12解释：</li> <li>并不是的，我的理解是由于CPU是64位的，所以还是默认<code>#pragma pack(8)</code>，编译器说32位也没用。</li> <li>『原因：你如果在前面进行强制的<code>#pragma pack(4)</code>，你就发现，答案是20而不是24，所以，我猜测这个是CPU的原因』</li> <li><font style="background:yellow;">CPU的位数很重要，或许决定了<code>#pragma pack()</code>的数字</font></li></ul> <h4 id="_5-1-3-alignof好的测试"><a href="#_5-1-3-alignof好的测试" class="header-anchor">#</a> 5.1.3.alignof好的测试</h4> <ul><li>alignof : 获取地址对齐的大小，POD里面最大的内存对其的大小。</li> <li>C 的 _Alignof 和 C++ 的 alignof 可以获得类型的对齐。</li></ul> <p>C语言中的<code>_Alignof</code>的<a href="https://cloud.tencent.com/developer/section/1009082" target="_blank" rel="noopener noreferrer">对齐<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <ul><li>环境64位CPU，64位编译器</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">struct</span> <span class="token class-name">node</span>
<span class="token punctuation">{</span>
    <span class="token comment">//char ss;</span>
	<span class="token keyword">struct</span> <span class="token class-name">temp</span>
	<span class="token punctuation">{</span>
		<span class="token keyword">char</span> a<span class="token punctuation">;</span>
		<span class="token keyword">int</span> b<span class="token punctuation">;</span>
		<span class="token keyword">double</span> c<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>	t<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;alignof(node):&quot;</span><span class="token operator">&lt;&lt;</span> <span class="token keyword">alignof</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
cout<span class="token operator">&lt;&lt;</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>node<span class="token punctuation">)</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>

<span class="token comment">//alignof(node):8</span>
<span class="token comment">//16</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><ul><li>如果加上<code>char ss;</code></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token comment">//alignof(node):8</span>
<span class="token comment">//24</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h2 id="_03-典例解释"><a href="#_03-典例解释" class="header-anchor">#</a> 03.典例解释</h2> <h3 id="_3-1-单个struct『good解释⭐️"><a href="#_3-1-单个struct『good解释⭐️" class="header-anchor">#</a> 3.1.单个<code>struct</code>『Good解释⭐️</h3> <h4 id="_3-1-1-可移植性"><a href="#_3-1-1-可移植性" class="header-anchor">#</a> 3.1.1.可移植性</h4> <ul><li>参考例题<a href="https://www.nowcoder.com/questionTerminal/ac4a46ee80b84313bb95307887ffb6c1" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>在一个<span class="token number">16</span>位的机器，以下结构由于边界对齐浪费了多少空间（）
复制代码
<span class="token keyword">struct</span><span class="token punctuation">{</span>
     <span class="token keyword">char</span> a<span class="token punctuation">;</span>
     <span class="token keyword">int</span> b<span class="token punctuation">;</span>
     <span class="token keyword">char</span> c<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
正确答案<span class="token operator">:</span> D   你的答案<span class="token operator">:</span> <span class="token function">D</span> <span class="token punctuation">(</span>正确<span class="token punctuation">)</span>
<span class="token number">8</span>
<span class="token number">4</span>
<span class="token number">6</span>
<span class="token number">2</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><p>解释：</p> <ul><li><font style="background:yellow;">由于<strong>可移植性</strong>导致：<code>16位</code>的机器上默认是<strong>2字节对齐『<code>#pragma pack(2)</code>』</strong>！那么该种机器中<code>int</code>只用2Byte</font>，并不是什么int 在16位上要拆分为2个short的???『好像也不对，因为用后面的也能解释是2,！！！，但是《C++Primer》规定int最小是可以有16位』</li> <li>1、自然对齐，min(char，『<code>#pragma pack(2)</code>』)=1，所以a是1个字节放在[0,0]</li> <li>2、自然对齐，min（int（注意，此机器上是2），『<code>#pragma pack(2)</code>』）=2，所以放在[2,3]</li> <li>3、自然对齐，min(char,『<code>#pragma pack(2)</code>』)=1，所以c是1个字节放在[4,4]</li> <li>4、规则对齐，是max(1,2,1)=2,所以是2的倍数，最接近是6，就是[0,5]
然后，char+int（此机器上是2）+char=6个字节
<ul><li>8-6=2个字节浪费</li></ul></li></ul> <h4 id="_3-1-2-面试记录"><a href="#_3-1-2-面试记录" class="header-anchor">#</a> 3.1.2.面试记录</h4> <ul><li>测试环境『64位编译器，，我觉得默认是64位CPU』</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token comment">// 你必须定义一个 `main()` 函数入口。</span>
<span class="token comment">//测试环境是：64位gcc编译器下输出</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
    <span class="token keyword">union</span> test
    <span class="token punctuation">{</span>
        <span class="token keyword">int</span> aa<span class="token punctuation">;</span>
        <span class="token keyword">int</span> bb<span class="token punctuation">;</span>
        <span class="token keyword">char</span> <span class="token operator">*</span>cc<span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">//徐晃一枪，没有变量被定义，仅仅是“声明”</span>
    <span class="token keyword">int</span> a<span class="token punctuation">;</span>
    <span class="token keyword">short</span> b<span class="token punctuation">;</span>
    <span class="token keyword">int</span> c<span class="token punctuation">;</span>
    <span class="token keyword">char</span> d<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">B</span>
<span class="token punctuation">{</span>
    <span class="token keyword">double</span> a<span class="token punctuation">;</span>
    <span class="token keyword">short</span> b<span class="token punctuation">;</span>
    <span class="token keyword">int</span> c<span class="token punctuation">;</span>
    <span class="token keyword">char</span> d<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>B<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
 <span class="token punctuation">}</span> 
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br></div></div><p>64位gcc下输出</p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">16</span>
<span class="token number">24</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>解释16原因：</p> <ul><li><p>64位的gcc编译器下对齐是『<code>#pragma pack(8)</code> 』</p></li> <li><p><font style="background:yellow;"><strong>坑点</strong>：union 没有初始化，但是struct中还有其他成员，我们就可以不用给它分配空间来占位置『如果只有它，我们需要1来占位』</font></p></li> <li><p><code>min（int(4) , 『#pragma pack(8)』）</code>  =4字节对齐，int 占据前4个</p></li> <li><p><code>min（short(2),『#pragma pack(8)』）</code>= 2字节对齐，short仅接着据2『后面，我们发现还要填补充』</p></li> <li><p><code>min（int(4) , 『#pragma pack(8)』）</code>  =4字节对齐，但是此时开始的位置不是4的倍数！『所以给前面的填pack』然后int 占据4个</p></li> <li><p><code>min（char(1) , 『#pragma pack(8)』）</code>  =1字节对齐，char紧接着占据1个  『后面，我们发现还要填补充』</p> <ul><li>这个时候，我们发现，获得的是13个字节</li></ul></li> <li><p>接着，结构体总大小进行对齐『我们需要采用前面弄到的</p> <ul><li>max（4,2,4,1）=4发现，最大对齐数是4</li> <li>那么，我们知道最近的是16</li></ul></li></ul> <p>解释24的原因：</p> <ul><li>64位的gcc编译器下对齐是『<code>#pragma pack(8)</code> 』</li></ul> <table><thead><tr><th>自然对齐</th> <th>占用的大小</th> <th>是否有补丁</th></tr></thead> <tbody><tr><td><code>min（double(8) , 『#pragma pack(8)』）</code>  =8字节对齐</td> <td>double占据前8个</td> <td>0</td></tr> <tr><td><code>min（short(2),『#pragma pack(8)』）</code>= 2字节对齐</td> <td>short仅接着据2『后面，我们发现还要填补充』</td> <td>2</td></tr> <tr><td><code>min（int(4) , 『#pragma pack(8)』）</code>  =4字节对齐，</td> <td>但是此时开始的位置不是4的倍数！『所以给前面的填pack』然后int 占据4个</td> <td>0</td></tr> <tr><td><code>min（char(1) , 『#pragma pack(8)』）</code>  =1字节对齐</td> <td>char紧接着占据1个  『后面，我们发现还要填补充』</td> <td></td></tr></tbody></table> <ul><li><p>这个时候，我们发现，获得的是13个字节</p></li> <li><p>接着，结构体总大小进行对齐『我们需要采用前面弄到的表格中第1列的值来求max』</p> <ul><li>max（4,2,4,1）=4发现，最大对齐数是4</li> <li>那么，我们知道最近的是16</li></ul></li></ul> <h3 id="_3-2-单个union『复杂内存对齐分析（面试）』"><a href="#_3-2-单个union『复杂内存对齐分析（面试）』" class="header-anchor">#</a> 3.2.单个<code>union</code>『复杂内存对齐分析（面试）』</h3> <ul><li>测试环境『64位编译器，，或许默认64位CPU』</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">struct</span> <span class="token class-name">one</span>
<span class="token punctuation">{</span>
	<span class="token keyword">char</span> a<span class="token punctuation">;</span><span class="token comment">//1-&gt;内存对齐（4） </span>
	<span class="token keyword">long</span> b<span class="token punctuation">;</span><span class="token comment">//4</span>
	<span class="token keyword">char</span> c<span class="token punctuation">;</span> 
	<span class="token keyword">union</span> test
	<span class="token punctuation">{</span>
		<span class="token keyword">int</span> aa<span class="token punctuation">;</span>
		<span class="token keyword">char</span> bb<span class="token punctuation">;</span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment">//没有实例化，不用管 </span>
	
	
	<span class="token keyword">double</span> k<span class="token punctuation">;</span>
	<span class="token keyword">int</span> <span class="token operator">*</span> p<span class="token punctuation">;</span><span class="token comment">//32位机器 </span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token keyword">struct</span> <span class="token class-name">two</span>
<span class="token punctuation">{</span>
	
	<span class="token keyword">union</span> test
	<span class="token punctuation">{</span>
		<span class="token keyword">int</span> aa<span class="token punctuation">;</span>
		<span class="token keyword">char</span> bb<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>demo<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token keyword">struct</span> <span class="token class-name">three</span>
<span class="token punctuation">{</span>
	
	<span class="token keyword">union</span> test
	<span class="token punctuation">{</span>
		<span class="token keyword">int</span> aa<span class="token punctuation">;</span>
		<span class="token keyword">char</span> bb<span class="token punctuation">;</span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>



<span class="token keyword">struct</span> <span class="token class-name">four</span>
<span class="token punctuation">{</span>
	
	<span class="token keyword">int</span> a<span class="token punctuation">;</span>
	<span class="token keyword">int</span> b<span class="token punctuation">;</span>
	<span class="token keyword">int</span> c<span class="token punctuation">;</span>
	<span class="token keyword">double</span> d<span class="token punctuation">;</span>
	
<span class="token punctuation">}</span>_four<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	
	<span class="token comment">//注意</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;sizeof(long)=%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	one _one<span class="token punctuation">;</span> 
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>_one<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	two _two<span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>_two<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	three _three<span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>_three<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">int</span> <span class="token operator">*</span> p<span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>_four<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br></div></div><ul><li>测试环境32位CPU</li> <li>『例子很好』题目<a href="https://www.nowcoder.com/questionTerminal/412ee424b496435095eafc8918ec0b56?orderByHotValue=1&page=1&onlyReference=false" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token keyword">struct</span> <span class="token class-name">test</span>
<span class="token punctuation">{</span> 
	<span class="token keyword">int</span> ml<span class="token punctuation">;</span>
	<span class="token keyword">char</span> m2<span class="token punctuation">;</span>
    <span class="token keyword">float</span> m3<span class="token punctuation">;</span>
	<span class="token keyword">union</span> uu
	<span class="token punctuation">{</span>
    	<span class="token keyword">char</span> ul<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
        <span class="token keyword">int</span> u2<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span> ua<span class="token punctuation">;</span>
<span class="token punctuation">}</span> myaa<span class="token punctuation">;</span>

问<span class="token number">32</span>位机器下<span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> <span class="token class-name">test</span> <span class="token punctuation">)</span>
答：<span class="token number">20</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><p>解释：</p> <ul><li><p>联合体的解释：</p></li> <li><p><code>min( char(1), #pragma pack(4) )</code>=1，我们的u1的5个元素，依次放到[0-4]</p></li> <li><p><code>min( int(4), #pragma pack(4) )</code>=4，我们的u2的2个元素，依次从[0-7]『注意，是从头开始！』</p></li> <li><p>然后，我们发现，最长的占用了8个Byte</p> <ul><li>接下来：规则对齐，<code>max(1,4)</code>=4，发现8是合理的，那么就占用8『注意，这个union整体的对齐数就是规则对齐数得到的——4『不要相成是8哈！！容易错』』</li></ul></li> <li><p>union外边的</p> <ul><li>int m1  4个</li> <li>char m2 1个</li> <li>float m3 4个
按照规则2和3，我们要按照默认的4字节对齐来对这些在结构体中重排列
m1  offset=0-3
m2	offset=4
offset=5-7不用，但是占领
m3	offset=8-11
union	offset=12-19
总共，占用5个内存块，一个20个字节。</li></ul></li></ul> <h3 id="_3-3-单个位段"><a href="#_3-3-单个位段" class="header-anchor">#</a> 3.3.单个位段</h3> <ul><li>可能嵌入式和网络编程中会用到这种用法：位段（也叫位域）一种特殊的类结构体语法</li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;stdio.h&gt;</span></span>

<span class="token keyword">struct</span> 
<span class="token punctuation">{</span>
   <span class="token keyword">int</span> a<span class="token operator">:</span><span class="token number">8</span><span class="token punctuation">;</span>
   <span class="token keyword">int</span> b<span class="token operator">:</span><span class="token number">2</span><span class="token punctuation">;</span>
   <span class="token keyword">int</span> c<span class="token operator">:</span><span class="token number">5</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>ab<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;%d\n&quot;</span><span class="token punctuation">,</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span>ab<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//输出4</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><h4 id="问题：sizeof（long-是4还是8的不同是由不同编译器决定的，还是操作系统的位数，还是电脑的位数，还是c的标准"><a href="#问题：sizeof（long-是4还是8的不同是由不同编译器决定的，还是操作系统的位数，还是电脑的位数，还是c的标准" class="header-anchor">#</a> 问题：sizeof（long)是4还是8的不同是由不同编译器决定的，还是操作系统的位数，还是电脑的位数，还是C的标准</h4> <ul><li>有人回答：这个是由编译器决定的，有的是32位编译器，有的是64位编译器，有的是标准C编译器，有的是C++编译器，都有可能不同</li> <li>『正确吗？？？』</li></ul> <h3 id="_3-4-数组和指针组合『难题』"><a href="#_3-4-数组和指针组合『难题』" class="header-anchor">#</a> 3.4.数组和指针组合『难题』</h3> <ul><li>题目<a href="https://www.nowcoder.com/questionTerminal/8f3ce8a749f34ae59b2f0efc46d3ace9" target="_blank" rel="noopener noreferrer">传送口<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-c line-numbers-mode"><pre class="language-c"><code>以下代码打印的结果是（假设运行在 <span class="token number">64</span> 位计算机上）：
<span class="token keyword">struct</span> <span class="token class-name">st_t</span> <span class="token punctuation">{</span>
    <span class="token keyword">int</span> status<span class="token punctuation">;</span>
    <span class="token keyword">short</span> <span class="token operator">*</span>pdata<span class="token punctuation">;</span>
    <span class="token keyword">char</span> errstr<span class="token punctuation">[</span><span class="token number">32</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">st_t</span> st<span class="token punctuation">[</span><span class="token number">16</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">char</span> <span class="token operator">*</span>p<span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>st<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span>esstr<span class="token operator">+</span><span class="token number">32</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">printf</span><span class="token punctuation">(</span>“<span class="token operator">%</span>d”<span class="token punctuation">,</span><span class="token punctuation">(</span>p<span class="token operator">-</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">(</span>st<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//题目来自——牛客网</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><ul><li><p>//上面这道题，我们暂时不分析最后的结果，我们只分析在64位的机器下的这个结构体占用的字节。</p></li> <li><p><font style="background:yellow;">因为是64位环境下，所以默认对齐方式是8字节为一个内存块</font></p></li></ul> <p><code>int status;</code>虽然int只占用4个 由于后面的指针八个字节放不下 填补不了空位 所以对其要八个字节(后面的4个为对齐位）
<code>short *pdata;</code>这个指针会占用8个字节<br> <code>char errstr[32];</code> 占用32个字节</p> <ul><li>所以一共占用 8+8+32=48个字节</li></ul> <p><code>char *p=(char *)(st[2].esstr+32)</code>，p实际指向了st[3]<br>
则<code>p-(char *)(st))</code>，即为<code>&amp;st[3]-&amp;st[0]</code>,占用空间为3个结构体的大小，即3*48=14</p></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/24.6f596516.js" defer></script>
  </body>
</html>
